Skip to content

fix(api-block): stop spoofing a browser fingerprint on outbound HTTP requests#5496

Merged
waleedlatif1 merged 2 commits into
stagingfrom
fix-api-block-basic-auth-xsrf
Jul 7, 2026
Merged

fix(api-block): stop spoofing a browser fingerprint on outbound HTTP requests#5496
waleedlatif1 merged 2 commits into
stagingfrom
fix-api-block-basic-auth-xsrf

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • API block requests rejected by Atlassian Jira Cloud with 403 XSRF check failed, even with a valid Basic-auth header and X-Atlassian-Token: no-check set. Identical requests via curl return 201 every time.
  • Root cause: getDefaultHeaders() (apps/sim/tools/http/utils.ts) unconditionally sent a Chrome User-Agent, a Referer pointing at Sim's own app domain, and mismatched Sec-Ch-Ua* client hints (UA claims Chrome 135, Sec-Ch-Ua claims Chromium v91) on every outbound API block request. Atlassian's own support KB confirms REST calls carrying a browser User-Agent can fail CSRF checks independent of X-Atlassian-Token.
  • This has been present since the API tool's default headers were introduced (April 2025) — not a recent regression, just previously undiagnosed against a strict target.
  • Fix: default headers now identify honestly as Sim/1.0 (+https://sim.ai), matching how curl/Postman/axios identify themselves. Dropped Referer and Sec-Ch-Ua* entirely — none are meaningful for a server-to-server API client. User-supplied headers continue to override any default (unchanged).

Test plan

  • bunx vitest run tools/http/request.test.ts — 26/26 pass (updated assertions for the new defaults + added coverage for default-absent and user-override cases)
  • tsc --noEmit clean on touched files
  • biome check clean on touched files

…requests

getDefaultHeaders() sent a Chrome User-Agent, a Referer pointing at Sim's
own app, and mismatched Sec-Ch-Ua client hints on every API block request.
Atlassian's Jira/Confluence Cloud REST API (and other browser-aware
anti-CSRF/bot-defense layers) reject requests carrying a browser
User-Agent with 403 "XSRF check failed", even with a valid Basic-auth
header and X-Atlassian-Token: no-check set.

Default headers now identify honestly as Sim, matching how other HTTP
clients (curl, Postman, axios) behave. User-supplied headers still
override any default.
@vercel

vercel Bot commented Jul 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 7, 2026 11:55pm

Request Review

@cursor

cursor Bot commented Jul 7, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes default headers on every API block request, which can alter behavior with strict WAFs or providers that expected the old browser fingerprint; user overrides remain unchanged.

Overview
Outbound HTTP/API block requests no longer send a Chrome User-Agent, Referer, or Sec-Ch-Ua* client hints by default. Defaults now use Sim/1.0 (+https://sim.ai) plus standard accept/cache/connection headers and dynamic Host, so integrations (e.g. Atlassian Jira) are less likely to fail CSRF checks triggered by browser-like fingerprints.

Tests assert the new defaults, that Referer is absent unless the user sets it, and that custom headers still override defaults. Shared test mocks in tool-tester.builder match the same header set.

Reviewed by Cursor Bugbot for commit 326ae91. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR removes browser-fingerprint headers (User-Agent impersonating Chrome, Referer, Sec-Ch-Ua*) from all outbound API block requests and replaces the UA with an honest Sim/1.0 (+https://sim.ai) identifier, resolving 403 CSRF failures against providers like Atlassian Jira Cloud.

  • apps/sim/tools/http/utils.ts: Strips four browser-fingerprint headers from getDefaultHeaders, removes the now-unused getBaseUrl import, and adds a JSDoc comment explaining the rationale with a link to Atlassian's KB article.
  • apps/sim/tools/http/request.test.ts: Replaces old window-mock boilerplate with targeted assertions verifying the new UA string, confirming absent browser headers, and adding a new test for user-supplied Referer override.
  • packages/testing/src/builders/tool-tester.builder.ts: Syncs createMockHeaders to mirror the new getDefaultHeaders defaults, eliminating a pre-existing drift where Referer was hardcoded to https://www.sim.ai in tests but dynamic in production.

Confidence Score: 5/5

Safe to merge — the change removes outbound headers that were actively causing request failures and replaces them with a correct server-to-server identity. User-supplied headers continue to override defaults unchanged.

The diff is minimal and surgical: four hardcoded browser-fingerprint headers are deleted from getDefaultHeaders, the unused getBaseUrl import is cleaned up, and tests are updated to match. No auth logic, no data paths, and no API contracts are affected. The test suite was extended with explicit coverage for the new UA value and the absence of removed headers.

No files require special attention.

Important Files Changed

Filename Overview
apps/sim/tools/http/utils.ts Removes browser-fingerprint headers and replaces Chrome UA with Sim/1.0 (+https://sim.ai); drops unused getBaseUrl import. Clean, minimal, well-documented change.
apps/sim/tools/http/request.test.ts Test assertions updated for new UA string and absent browser headers; window mock boilerplate removed; new test added for user-provided Referer override.
packages/testing/src/builders/tool-tester.builder.ts createMockHeaders synced to match updated getDefaultHeaders defaults, resolving a pre-existing drift where Referer and Sec-Ch-Ua headers were present in test helper but now removed from production code.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant U as User / Workflow
    participant AB as API Block
    participant GDH as getDefaultHeaders()
    participant T as Target API (e.g. Jira)

    U->>AB: Execute HTTP request
    AB->>GDH: getDefaultHeaders(customHeaders, url)
    Note over GDH: Before: User-Agent = Chrome 135<br/>Referer = sim.ai<br/>Sec-Ch-Ua* = Chromium v91
    Note over GDH: After: User-Agent = Sim/1.0 (+https://sim.ai)<br/>No Referer, no Sec-Ch-Ua*
    GDH-->>AB: "{ User-Agent, Accept, Accept-Encoding, Cache-Control, Connection, Host, ...customHeaders }"
    AB->>T: "fetch(url, { headers })"
    alt Before fix
        T-->>AB: 403 XSRF check failed
    else After fix
        T-->>AB: 201 Created
    end
    AB-->>U: Response
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant U as User / Workflow
    participant AB as API Block
    participant GDH as getDefaultHeaders()
    participant T as Target API (e.g. Jira)

    U->>AB: Execute HTTP request
    AB->>GDH: getDefaultHeaders(customHeaders, url)
    Note over GDH: Before: User-Agent = Chrome 135<br/>Referer = sim.ai<br/>Sec-Ch-Ua* = Chromium v91
    Note over GDH: After: User-Agent = Sim/1.0 (+https://sim.ai)<br/>No Referer, no Sec-Ch-Ua*
    GDH-->>AB: "{ User-Agent, Accept, Accept-Encoding, Cache-Control, Connection, Host, ...customHeaders }"
    AB->>T: "fetch(url, { headers })"
    alt Before fix
        T-->>AB: 403 XSRF check failed
    else After fix
        T-->>AB: 201 Created
    end
    AB-->>U: Response
Loading

Reviews (2): Last reviewed commit: "fix(testing): sync shared tool-tester mo..." | Re-trigger Greptile

createMockHeaders in the shared @sim/testing tool-tester builder still
hardcoded the old Chrome UA / Referer / Sec-Ch-Ua fallback values. It was
unreachable in current tests but would silently diverge from production
getDefaultHeaders() for any future test hitting its fallback path.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptileai review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 326ae91. Configure here.

@waleedlatif1 waleedlatif1 merged commit 858f7d2 into staging Jul 7, 2026
13 checks passed
@waleedlatif1 waleedlatif1 deleted the fix-api-block-basic-auth-xsrf branch July 7, 2026 23:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant